﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Xml;
using Common.Utilities;
using Workflows.Components.Rules.Properties;

namespace Workflows.Components.Rules
{
    /// <summary>
    /// abstract base class that contains rule node data 
    /// </summary>
    [Serializable]
    public abstract class RuleNodeDataBase  
    {
        private Guid _RuleNodeID;
        /// <summary></summary>
        public Guid RuleNodeID
        {
            get
            {
                return this._RuleNodeID;
            }
            set
            {
                this._RuleNodeID = value;
            }
        }

        private RuleNodeType _RuleNodeType;
        /// <summary>
        /// 
        /// </summary>
        public RuleNodeType RuleNodeType
        {
            get
            {
                return this._RuleNodeType;
            }
            set
            {
                this._RuleNodeType = value;
            }
        }

        private string _Name;
        /// <summary></summary>
        public string Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                this._Name = value;
            }
        }

        private string _Description;
        /// <summary></summary>
        public string Description
        {
            get
            {
                return this._Description;
            }
            set
            {
                this._Description = value;
            }
        }

        private Image _Img;
        /// <summary></summary>
        public Image Img
        {
            get
            {
                return this._Img;
            }
            set
            {
                if (value.Width != 20 || value.Height != 20)
                {
                    Bitmap bmp = new Bitmap(20, 20);
                    Graphics g = Graphics.FromImage(bmp);
                    g.DrawImage(value, new Rectangle(0, 0, bmp.Width, bmp.Height),
                                new Rectangle(0, 0, value.Width, value.Height),
                                GraphicsUnit.Pixel);
                    g.Dispose();
                    this._Img = bmp;
                }
                else
                    this._Img = value;
            }
        }

        private Guid _FromNodeID;
        /// <summary>upstream rule node id</summary>
        public Guid FromNodeID
        {
            get
            {
                return this._FromNodeID;
            }
            set
            {
                this._FromNodeID = value;
            }
        }

        private string _FromNodeBranch;
        /// <summary>
        /// default to empty string, only "true"/"false"
        /// following the condition node
        /// </summary>
        public string FromNodeBranch
        {
            get
            {
                return this._FromNodeBranch;
            }
            set
            {
                this._FromNodeBranch = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public RuleNodeDataBase()
        {
            this._RuleNodeID = Guid.NewGuid();
            this._Name = "Condition";
            this._Description = "Condition";
            this._Img = Resources.Search;
            this._RuleNodeType = Rules.RuleNodeType.Conditional;
            this._FromNodeID = Guid.Empty;
            this._FromNodeBranch = string.Empty;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xDoc"></param>
        /// <param name="parentNode"></param>
        public virtual XmlNode Serialize(ref XmlDocument xDoc, ref XmlNode parentNode)
        {
            XmlNode xNode = XmlDataUtil.AddElement(ref xDoc, parentNode, "RuleNode");
            XmlDataUtil.UpdateAttribute(ref xDoc,xNode,"RuleNodeID",this.RuleNodeID.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode,"RuleNodeType",((int)this.RuleNodeType).ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode,"Name",this.Name);
            XmlDataUtil.UpdateAttribute(ref xDoc,xNode,"Description",this.Description);
            return xNode;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xNode"></param>
        /// <returns></returns>
        public abstract RuleNodeDataBase Instantiate(XmlNode xNode);

        /// <summary>
        /// return html description
        /// </summary>
        /// <returns></returns>
        public abstract string DescribeInHtml();

        /// <summary>
        /// return text description
        /// </summary>
        /// <returns></returns>
        public abstract string Describe();

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public RuleNodeDataBase Clone()
        {
            XmlDocument xDoc=new XmlDocument();
            xDoc.LoadXml("<RuleNodeData></RuleNodeData>");
            XmlNode root = xDoc.DocumentElement;
            XmlNode xNode = this.Serialize(ref xDoc, ref root);
            RuleNodeDataBase ruleNodeData = this.Instantiate(xNode);
            ruleNodeData.RuleNodeID = Guid.NewGuid();
            return ruleNodeData;
        }
    }
}
